<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        @import url(http://fonts.useso.com/css?family=Raleway:100);
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        body {
            background: #1d1f20;
            font-family: "Raleway", sans-serif;
            font-weight: 200;
        }
        .container {
            text-align: center;
            width: 100%;
            height: 100%;
        }
        canvas,
        .text {
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
        }
        .text {
            display: table;
            margin: auto;
            height: 100%;
            width: 100%;
        }
        .wrapper {
            widows: 100%;
            height: 100%;
            display: table-cell;
            vertical-align: middle;
            color: #fff;
        }
        h1 {
            font-size: 100px;
            text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
        }
        p {
            max-width: 70%;
            margin: auto;
            font-size: 30px;
            text-shadow: 0 0 5px white;
        }
    </style>
</head>
<body>
<div class="container">
    <canvas id="cs"></canvas>
    <canvas id="mask"></canvas>
    <div class="text">
        <div class="wrapper">
            <h1>Canvas moving rainbow</h1>
        </div>
    </div>
</div>
</body>
</html>

<script>
    var cs = document.getElementById('cs');
    var mask = document.getElementById('mask');
    var cx = cs.getContext('2d');
    var maskCx = mask.getContext('2d');
    var windowW = window.innerWidth;
    var windowH = window.innerHeight;

    cx.canvas.width = windowW;
    cx.canvas.height = windowH;
    maskCx.canvas.width = windowW;
    maskCx.canvas.height = windowH;

    var createGrad = function(x, y) {
        var grad = cx.createRadialGradient(x, y, 0, y + windowH, x + windowW, windowW * 3);
        grad.addColorStop(0, 'rgba(228, 3, 3, 0.5)');
        grad.addColorStop(.02, 'rgba(255, 140, 0, 0.5)');
        grad.addColorStop(.08, 'rgba(255, 237, 0, 0.5)');
        grad.addColorStop(.14, 'rgba(0, 128, 38, 0.5)');
        grad.addColorStop(.2, 'rgba(0, 77, 255, 0.5)');
        grad.addColorStop(.26, 'rgba(117, 7, 135, 0.5)');
        return grad;
    };

    var refreshGrad = function(x, y) {
        var grad = createGrad(x, y);
        cx.fillStyle = grad;
        cx.fillRect(0, 0, windowW, windowH);
    };

    var trackMousePosition = function(e) {
        var x = e.pageX;
        var y = e.pageY;
        refreshGrad(x, y);
        refreshMask();
    };

    document.onmousemove = trackMousePosition;

    refreshGrad(windowW / 2, windowH);

    //mask
    maskCx.beginPath();
    maskCx.moveTo(0, 0);

    //counter clockwise rect
    maskCx.lineTo(0, windowH);
    maskCx.lineTo(windowW, windowH);
    maskCx.lineTo(windowW, 0);
    maskCx.lineTo(0, 0);

    //clockwise dots
    for (var j = 0; j < windowW / 4; j++) {
        for (var i = 0; i < windowH / 4; i++) {
            maskCx.moveTo(4 * j, 4 * i);
            maskCx.arc(4 * j, 4 * i, .75, 0, 2 * Math.PI);
        }
    }

    maskCx.fillStyle = "rgba(0,0,0,.8)"
    maskCx.fill();
</script>